package org.linlinjava.litemall.admin.service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.shiro.SecurityUtils;
import org.linlinjava.litemall.admin.beans.Constants;
import org.linlinjava.litemall.admin.beans.dto.MessageDto;
import org.linlinjava.litemall.core.notify.NoticeHelper;
import org.linlinjava.litemall.core.notify.netty.PushService;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.db.domain.LitemallAdmin;
import org.linlinjava.litemall.db.domain.LitemallMessage;
import org.linlinjava.litemall.db.domain.LitemallUser;
import org.linlinjava.litemall.db.service.LitemallMessageService;
import org.linlinjava.litemall.db.service.LitemallUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

/**
 * 消息服务
 *
 * @author yliyun
 * @date 2022/09/14
 */
@Service
public class MessageService {
    /**
     * 日志
     */
    private Log log = LogFactory.getLog(MessageService.class);

    /**
     * 消息服务
     */
    @Autowired
    private LitemallMessageService messageService;
    /**
     * 推动服务
     */
    @Autowired
    private PushService pushService;
    /**
     * litemall用户服务
     */
    @Autowired
    private LitemallUserService litemallUserService;
    /**
     * 注意助手
     */
    @Autowired
    private NoticeHelper noticeHelper;

    /**
     * 查询消息列表
     *
     * @param title 标题
     * @param type  类型
     * @param page  页面
     * @param limit 限制
     * @param sort  排序
     * @param order 订单
     * @return {@link Object}
     */
    public Object queryMessageList(String title, Byte type,
                                   Integer page, Integer limit, String sort, String order) {
        return ResponseUtil.okList(messageService.querySelective(title, type, page, limit, sort, order));
    }

    /**
     * 插入
     *
     * @param messageDto 消息dto
     * @return {@link Object}
     */
    public Object insert(MessageDto messageDto) {
        if(null == messageDto.getMessage() || StringUtils.isEmpty(messageDto.getMessage().getTitle()) || StringUtils.isEmpty(messageDto.getMessage().getContent())){
            return ResponseUtil.badArgument();
        }
        LitemallMessage message = messageDto.getMessage();
        LitemallAdmin admin = (LitemallAdmin)SecurityUtils.getSubject().getPrincipal();
        message.setAddUserId(admin.getId());
        message.setAddUserName(admin.getUsername());
        messageService.create(message);
        sendMessage(messageDto);
        log.info("**********************");
/*        if(messageDto.getUsers() != null && messageDto.getUsers().size() > 0){
            for (Integer userId:
            messageDto.getUsers()) {
                LitemallMessageReceiver receiver = new LitemallMessageReceiver();
                receiver.setMessageId(messageId);
                receiver.setUserId(userId);
                receiverService.create(receiver);
            }
        }*/
        return ResponseUtil.ok();
    }

    /**
     * 更新
     *
     * @param litemallMessage litemall消息
     * @return {@link Object}
     */
    public Object update(LitemallMessage litemallMessage) {
        messageService.updateById(litemallMessage);
        return ResponseUtil.ok();
    }

    /**
     * 删除
     *
     * @param messageId 消息id
     * @return {@link Object}
     */
    public Object delete(Integer messageId) {
        messageService.deleteById(messageId);
        return ResponseUtil.ok();
    }


    /**
     * 发送消息
     *
     * @param messageDto 消息dto
     */
    @Async
    public void sendMessage(MessageDto messageDto){
        LitemallMessage message = messageDto.getMessage();
        log.info("sendMessage start param :" + message.toString());
        if(message.getType() == Constants.MESSAGE_TYPE_SYSTEM){
            pushService.pushMsgToAll(message.getContent());
            noticeHelper.noticeAll(Constants.MSG_TYPE_SYSTEM, message.getContent(), Constants.JPUSH_TITLE_SYSTEM, message);

        }else if(message.getType() == Constants.MESSAGE_TYPE_LEVEL){
            Integer[] receiverLevels = message.getReceiverLevels();

            if(receiverLevels != null && receiverLevels.length > 0){
                List<Byte> levels = new ArrayList<>();
                for(Integer level : receiverLevels){
                    levels.add(level.byteValue());
                }
                List<LitemallUser>  users = litemallUserService.queryByUserLevels(levels);
                sendNotice(users,messageDto);
            }else{
                List<LitemallUser> users = new ArrayList<>();
                sendNotice(users,messageDto);
            }

        }
    }

    /**
     * 发送通知
     *
     * @param users      用户
     * @param messageDto 消息dto
     */
    public void sendNotice(List<LitemallUser> users,MessageDto messageDto){
        List<Integer> us =  messageDto.getUsers();
         LitemallMessage message = messageDto.getMessage();

//        us.stream().forEach( u -> {
//            if(users.size() > 0 ){
//                users.stream().forEach(user -> {
//                    if(!user.getId().equals(u)){
//                        LitemallUser addUser = litemallUserService.findById(u);
//                        users.add(addUser);
//                    }
//                });
//            }else{
//                LitemallUser addUser = litemallUserService.findById(u);
//                users.add(addUser);
//            }
//        });

          List<Integer> existUserIds = users.stream().map(LitemallUser::getId).collect(Collectors.toList());
        for (int i = 0; i < us.size(); i++) {
            if(!existUserIds.contains(us.get(i))){
                LitemallUser u = litemallUserService.findById(us.get(i));
                users.add(u);
            }
        }

        users.forEach(user -> {
            noticeHelper.noticeUser(Constants.MSG_TYPE_OTHER, Constants.JPUSH_TITLE_SYSTEM,  message.getContent(),user.getId(), message);
            pushService.pushMsgToOne(String.valueOf(user.getId()), message.getContent());
        });
    }
}
